package com.easipass.framework.eirframeworkcoredsl;

import java.text.MessageFormat;


public enum DSLMessage {

    NO_WHITESPACE_BEFORE_ARG_NAME(Kind.ERROR, 100, "No whitespace allowed between '--' and option name"), //
    NO_WHITESPACE_BEFORE_ARG_EQUALS(Kind.ERROR, 101, "No whitespace allowed after argument name and before '='"), //
    NO_WHITESPACE_BEFORE_ARG_VALUE(Kind.ERROR, 102, "No whitespace allowed after '=' and before option value"), //
    EXPECTED_ARGUMENT_VALUE(Kind.ERROR, 103, "Expected an argument value but was ''{0}''"), //
    NON_TERMINATING_DOUBLE_QUOTED_STRING(Kind.ERROR, 104, "Cannot find terminating \" for string"), //
    NON_TERMINATING_QUOTED_STRING(Kind.ERROR, 105, "Cannot find terminating '' for string"), //
    MISSING_CHARACTER(Kind.ERROR, 106, "missing expected character ''{0}''"), //
    NOT_EXPECTED_TOKEN(Kind.ERROR, 107, "Unexpected token.  Expected ''{0}'' but was ''{1}''"), //
    OOD(Kind.ERROR, 108, "Unexpectedly ran out of input"), //
    UNEXPECTED_ESCAPE_CHAR(Kind.ERROR, 109, "unexpected escape character."), //
    UNEXPECTED_DATA(Kind.ERROR, 110, "unexpected data in application definition ''{0}''"), //
    EXPECTED_APPNAME(Kind.ERROR, 111, "expected app name but found ''{0}''"), //
    EXPECTED_WHITESPACE_AFTER_APP_BEFORE_ARGUMENT(Kind.ERROR, 112, "expected whitespace after app name and before argument"), //
    ILLEGAL_APP_NAME(Kind.ERROR, 113, "illegal name for a application ''{0}''"), //
    NO_WHITESPACE_IN_DESTINATION_DEFINITION(Kind.ERROR, 114, "no whitespace allowed between components in a destination " + "name"), //
    NO_WHITESPACE_IN_DOTTED_NAME(Kind.ERROR, 115, "no whitespace is allowed between dot and components of a name"),
    SERVICE_DOUBLE_AND_REQUIRED(Kind.ERROR, 116, "service dsl flow requires a pair of &, not just one"), //
    SERVICE_DOUBLE_OR_REQUIRED(Kind.ERROR, 117, "service dsl requires a pair of '|'"), //
    SERVICE_MISSING_TRANSITION_ARROW(Kind.ERROR, 118, "expected '->' to follow state when specifying transition"), //
    SERVICE_UNQUOTED_TRANSITION_CHECK_MUST_BE_NUMBER(Kind.ERROR, 119,  "transition conditions must be quoted literals, numerics or '*' but ''{0}'' is not"), //
    SERVICE_NO_LABELS_ON_PARENS(Kind.ERROR, 120, "labels cannot be specified on parenthesized groups"), //
    SERVICE_NO_DOUBLE_LABELS(Kind.ERROR, 121, "double labels are not supported"), //
    SERVICE_ARROW_SHOULD_BE_PRECEDED_BY_CODE(Kind.ERROR, 122, "transition arrow must be preceeded by the exit code that should drive the transition"), //
    SERVICE_VALIDATION_SECONDARY_SEQUENCES_MUST_BE_NAMED(Kind.ERROR, 123,  "secondary sequences must have labels or are " + "unreachable"), //
    SERVICE_VALIDATION_DUPLICATE_LABEL(Kind.ERROR, 124, "this label has already been defined"), //
    SERVICE_VALIDATION_TRANSITION_TARGET_LABEL_UNDEFINED(Kind.ERROR, 125, "transition specifies an undefined label"), //
    SERVICE_MORE_INPUT(Kind.ERROR, 126, "after parsing a valid service, there is still more data: ''{0}''"), //
    SERVICE_VALIDATION_LABEL_CLASHES_WITH_APP_NAME(Kind.ERROR, 127,  "the label clashes with an existing unlabeled service application name"), //
    SERVICE_VALIDATION_APP_NAME_CLASHES_WITH_LABEL(Kind.ERROR, 128, "the app name clashes with an existing label"), //
    SERVICE_VALIDATION_APP_NAME_ALREADY_IN_USE(Kind.ERROR, 129, "duplicate app name. Use a label to ensure uniqueness"), //
    SERVICE_ARGUMENTS_NOT_ALLOWED_UNLESS_IN_APP_MODE(Kind.ERROR, 130, "arguments not allowed unless parser is in app mode"), //
    UNEXPECTED_DATA_IN_DESTINATION_NAME(Kind.ERROR, 131, "unexpected data in destination name ''{0}''"), //
    ;

    private Kind kind;

    private int code;

    private String message;

    DSLMessage(Kind kind, int code, String message) {
        this.kind = kind;
        this.code = code;
        this.message = message;
    }

    public String formatMessage(int pos, Object... inserts) {
        StringBuilder formattedMessage = new StringBuilder();
        formattedMessage.append(code);
        formattedMessage.append("E");
        formattedMessage.append(":");
        if (pos != -1) {
            formattedMessage.append("(pos ").append(pos).append("): ");
        }
        formattedMessage.append(MessageFormat.format(message, inserts));
        return formattedMessage.toString();
    }

    public Kind getKind() {
        return kind;
    }

    public enum Kind {
        INFO,
        WARNING,
        ERROR
    }
}
